﻿using System;
namespace SocketServer
{
    /// <summary>
    /// JS可以通过该方式链接到服务端
    /// </summary>
    public class WebSocketServerHelper : IDisposable
    {
        /// <summary>
        /// 实例化
        /// </summary>
        /// <param name="url">链接 示例:"ws://127.0.0.1:8888"</param>
        public WebSocketServerHelper(string url)
        {
            this.url = url;
        }

        #region 属性 字段
        /// <summary>
        /// Socket服务
        /// </summary>
        public string url { get; private set; }

        /// <summary>
        /// Socket服务
        /// </summary>
        public Fleck.WebSocketServer server { get; private set; }

        /// <summary>
        /// 链接Socket事件
        /// </summary>
        public event Action<Fleck.IWebSocketConnection> OpenEvent;

        /// <summary>
        /// 关闭Socket事件
        /// </summary>
        public event Action<Fleck.IWebSocketConnection> CloseEvent;

        /// <summary>
        /// 接受到客户端发送的消息事件
        /// </summary>
        /// <remarks>
        /// string 是客户端发送的消息
        /// </remarks>
        public event Action<Fleck.IWebSocketConnection, string> MessageEvent;

        /// <summary>
        /// 接受到客户端发送的byte[]事件
        /// </summary>
        /// <remarks>
        /// 文件流等数据是byte[]
        /// </remarks>
        public event Action<Fleck.IWebSocketConnection, byte[]> MessageBytesEvent;

        /// <summary>
        /// 是否启动了socket服务端
        /// </summary>
        public bool IsSatrt { get; protected set; }
        #endregion

        /// <summary>
        /// 触发文本消息处理事件(MessageEvent)
        /// </summary>
        /// <param name="socket">客户端Socket</param>
        /// <param name="message">文本消息</param>
        protected virtual void OnMessage(Fleck.IWebSocketConnection socket, string message)
        {
            if (MessageEvent != null)
            {
                MessageEvent(socket, message);
                return;
            }
        }

        /// <summary>
        /// 触发byte[]消息处理事件(MessageBytesEvent)
        /// </summary>
        /// <param name="socket">客户端Socket</param>
        /// <param name="message">byte数组消息</param>
        protected virtual void OnMessageBytesEvent(Fleck.IWebSocketConnection socket, byte[] message)
        {
            if (MessageBytesEvent != null)
            {
                MessageBytesEvent(socket, message);
                return;
            }
        }

        /// <summary>
        /// Socket客户端断开时处理
        /// </summary>
        /// <param name="socket">客户端Socket</param>
        protected virtual void OnClose(Fleck.IWebSocketConnection socket)
        {
            if (CloseEvent != null)
            {
                CloseEvent(socket);
                return;
            }
        }

        /// <summary>
        /// 触发OpenEvent
        /// </summary>
        /// <param name="socket">客户端Socket</param>
        protected virtual void OnOpen(Fleck.IWebSocketConnection socket)
        {
            if (OpenEvent != null)
            {
                OpenEvent(socket);
                return;
            }
        }

        /// <summary>
        /// 开启
        /// </summary>
        public virtual void Start()
        {
            if (IsSatrt)
            {
                return;
            }
            IsSatrt = true;
            server = new Fleck.WebSocketServer(url);
            server.Start(socket =>
            {
                //开启事件
                socket.OnOpen = () =>
                {
                    //Console.WriteLine(socket.ConnectionInfo.Host + "连接成功");
                    OnOpen(socket);
                };

                //关闭事件
                socket.OnClose = () =>
                {
                    //Console.WriteLine(socket.ConnectionInfo.Host + "断开连接");
                    OnClose(socket);
                };

                //接受消息事件
                socket.OnMessage = message =>
                {
                    OnMessage(socket, message);
                };

                socket.OnBinary = bytes =>
                {
                    OnMessageBytesEvent(socket, bytes);
                };

                socket.OnPong = bytes =>
                {

                };

                socket.OnPing = bytes =>
                {

                };
            });
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            IsSatrt = false;
            server.Dispose();
        }
    }
}
